home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / DirectInput / DIConfig / registry.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-27  |  8.2 KB  |  315 lines

  1. //-----------------------------------------------------------------------------
  2. // File: registry.cpp
  3. //
  4. // Desc: Contains COM register and unregister functions for the UI.
  5. //
  6. // Copyright (C) Microsoft Corporation. All Rights Reserved.
  7. //-----------------------------------------------------------------------------
  8.  
  9. #include "common.hpp"
  10.  
  11. ////////////////////////////////////////////////////////
  12. //
  13. // Internal helper functions prototypes
  14. //
  15.  
  16. // Set the given key and its value.
  17. BOOL setKeyAndValue(LPCTSTR pszPath,
  18.                     LPCTSTR szSubkey,
  19.                     LPCTSTR szValue);
  20.  
  21. // Set named value.
  22. BOOL setNamedValue(LPCTSTR pszPath,
  23.                    LPCTSTR szSubkey,
  24.                    LPCTSTR szKeyName,
  25.                    LPCTSTR szValue);
  26.  
  27.  
  28.  
  29. // Convert a CLSID into a char string.
  30. void CLSIDtochar(const CLSID& clsid,
  31.                  LPTSTR szCLSID,
  32.                  int length);
  33.  
  34. // Delete szKeyChild and all of its descendents.
  35. LONG recursiveDeleteKey(HKEY hKeyParent, LPCTSTR szKeyChild);
  36.  
  37. ////////////////////////////////////////////////////////
  38. //
  39. // Constants
  40. //
  41.  
  42. // Size of a CLSID as a string
  43. const int CLSID_STRING_SIZE = 39 ;
  44.  
  45. /////////////////////////////////////////////////////////
  46. //
  47. // Public function implementation
  48. //
  49.  
  50. //
  51. // Register the component in the registry.
  52. //
  53. HRESULT RegisterServer(HMODULE hModule,        // DLL module handle
  54.                        const CLSID& clsid,     // Class ID
  55.                        LPCTSTR szFriendlyName, // Friendly Name
  56.                        LPCTSTR szVerIndProgID, // Programmatic
  57.                        LPCTSTR szProgID)       // IDs
  58. {
  59.     // Get server location.
  60.     TCHAR szModule[512];
  61.     DWORD dwResult =
  62.         ::GetModuleFileName(hModule,
  63.                             szModule,
  64.                             sizeof(szModule)/sizeof(TCHAR));
  65.     if (!dwResult) return E_FAIL;
  66.  
  67.     // Convert the CLSID into a char.
  68.     TCHAR szCLSID[CLSID_STRING_SIZE];
  69.     CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)/sizeof(TCHAR));
  70.  
  71.     // Build the key CLSID\\{...}
  72.     TCHAR szKey[64];
  73.     _tcscpy(szKey, _T("CLSID\\"));
  74.     _tcscat(szKey, szCLSID);
  75.  
  76.     TCHAR szThreadKey[64];
  77.     _tcscpy(szThreadKey, szKey);
  78.     _tcscat(szThreadKey, _T("\\InProcServer32"));
  79.  
  80.     // Add the CLSID to the registry.
  81.     setKeyAndValue(szKey, NULL, szFriendlyName);
  82.  
  83.     // Add the server filename subkey under the CLSID key.
  84.     setKeyAndValue(szKey, _T("InProcServer32"), szModule);
  85.  
  86.     // Add the threading model subkey under the CLSID key
  87.     setNamedValue(szKey, _T("InProcServer32"), _T("ThreadingModel"), _T("Both"));
  88.  
  89.     // Add the ProgID subkey under the CLSID key.
  90.     setKeyAndValue(szKey, _T("ProgID"), szProgID);
  91.  
  92.     // Add the version-independent ProgID subkey under CLSID key.
  93.     setKeyAndValue(szKey, _T("VersionIndependentProgID"),
  94.                    szVerIndProgID);
  95.  
  96.     // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
  97.     setKeyAndValue(szVerIndProgID, NULL, szFriendlyName);
  98.     setKeyAndValue(szVerIndProgID, _T("CLSID"), szCLSID);
  99.     setKeyAndValue(szVerIndProgID, _T("CurVer"), szProgID);
  100.  
  101.     // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
  102.     setKeyAndValue(szProgID, NULL, szFriendlyName);
  103.     setKeyAndValue(szProgID, _T("CLSID"), szCLSID);
  104.  
  105.     return S_OK;
  106. }
  107.  
  108. //
  109. // Remove the component from the registry.
  110. //
  111. LONG UnregisterServer(const CLSID& clsid,     // Class ID
  112.                       LPCTSTR szVerIndProgID, // Programmatic
  113.                       LPCTSTR szProgID)       //   IDs
  114. {
  115.     // Convert the CLSID into a char.
  116.     TCHAR szCLSID[CLSID_STRING_SIZE];
  117.     CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)/sizeof(TCHAR));
  118.  
  119.     // Build the key CLSID\\{...}
  120.     TCHAR szKey[64];
  121.     _tcscpy(szKey, _T("CLSID\\"));
  122.     _tcscat(szKey, szCLSID);
  123.  
  124.     // Delete the CLSID Key - CLSID\{...}
  125.     LONG lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szKey);
  126.     assert((lResult == ERROR_SUCCESS) ||
  127.            (lResult == ERROR_FILE_NOT_FOUND)); // Subkey may not exist.
  128.  
  129.     // Delete the version-independent ProgID Key.
  130.     lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID);
  131.     assert((lResult == ERROR_SUCCESS) ||
  132.            (lResult == ERROR_FILE_NOT_FOUND)); // Subkey may not exist.
  133.  
  134.     // Delete the ProgID key.
  135.     lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID);
  136.     assert((lResult == ERROR_SUCCESS) ||
  137.            (lResult == ERROR_FILE_NOT_FOUND)); // Subkey may not exist.
  138.  
  139.     return S_OK;
  140. }
  141.  
  142. ///////////////////////////////////////////////////////////
  143. //
  144. // Internal helper functions
  145. //
  146.  
  147. // Convert a CLSID to a char string.
  148. void CLSIDtochar(const CLSID& clsid,
  149.                  LPTSTR szCLSID,
  150.                  int length)
  151. {
  152.     if (length < CLSID_STRING_SIZE)
  153.         return;
  154.  
  155.     // Get CLSID
  156.     LPOLESTR wszCLSID = NULL;
  157.     HRESULT hr = StringFromCLSID(clsid, &wszCLSID);
  158.     assert(SUCCEEDED(hr));
  159.  
  160.     if (!wszCLSID) return;
  161.  
  162. #ifdef _UNICODE
  163.     _tcsncpy(szCLSID, wszCLSID, length);
  164. #else
  165.     // Covert from wide characters to non-wide.
  166.     wcstombs(szCLSID, wszCLSID, length);
  167. #endif
  168.  
  169.     // Free memory.
  170.     CoTaskMemFree(wszCLSID);
  171. }
  172.  
  173. //
  174. // Delete a key and all of its descendents.
  175. //
  176. LONG recursiveDeleteKey(HKEY hKeyParent,       // Parent of key to delete
  177.                         LPCTSTR lpszKeyChild)  // Key to delete
  178. {
  179.     // Open the child.
  180.     HKEY hKeyChild;
  181.     LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0,
  182.                              KEY_ALL_ACCESS, &hKeyChild);
  183.     if (lRes != ERROR_SUCCESS)
  184.     {
  185.         return lRes;
  186.     }
  187.  
  188.     // Enumerate all of the decendents of this child.
  189.     FILETIME time;
  190.     TCHAR szBuffer[256];
  191.     DWORD dwSize = 256;
  192.     while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,
  193.            NULL, NULL, &time) == ERROR_SUCCESS)
  194.     {
  195.         // Delete the decendents of this child.
  196.         lRes = recursiveDeleteKey(hKeyChild, szBuffer);
  197.         if (lRes != ERROR_SUCCESS)
  198.         {
  199.             // Cleanup before exiting.
  200.             RegCloseKey(hKeyChild);
  201.             return lRes;
  202.         }
  203.         dwSize = 256;
  204.     }
  205.  
  206.     // Close the child.
  207.     RegCloseKey(hKeyChild);
  208.  
  209.     // Delete this child.
  210.     return RegDeleteKey(hKeyParent, lpszKeyChild);
  211. }
  212.  
  213. //
  214. // Create a key and set its value.
  215. //
  216. BOOL setKeyAndValue(LPCTSTR szKey,
  217.                     LPCTSTR szSubkey,
  218.                     LPCTSTR szValue)
  219. {
  220.     HKEY hKey;
  221.     LPTSTR szKeyBuf;
  222.  
  223.     if (szKey == NULL) return FALSE;
  224.  
  225.     // Allocate space
  226.     szKeyBuf = new TCHAR[lstrlen(szKey) + lstrlen(szSubkey) + 2];
  227.     if (!szKeyBuf) return FALSE;
  228.  
  229.     // Copy keyname into buffer.
  230.     _tcscpy(szKeyBuf, szKey);
  231.  
  232.     // Add subkey name to buffer.
  233.     if (szSubkey != NULL)
  234.     {
  235.         _tcscat(szKeyBuf, _T("\\"));
  236.         _tcscat(szKeyBuf, szSubkey );
  237.     }
  238.  
  239.     // Create and open key and subkey.
  240.     long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT,
  241.                                   szKeyBuf,
  242.                                   0, NULL, REG_OPTION_NON_VOLATILE,
  243.                                   KEY_ALL_ACCESS, NULL,
  244.                                   &hKey, NULL);
  245.     if (lResult != ERROR_SUCCESS)
  246.     {
  247.         delete[] szKeyBuf;
  248.         return FALSE;
  249.     }
  250.  
  251.     // Set the Value.
  252.     if (szValue != NULL)
  253.     {
  254.         RegSetValueEx(hKey, NULL, 0, REG_SZ,
  255.                       (BYTE *)szValue,
  256.                       sizeof(TCHAR) * ( _tcslen(szValue)+1) );
  257.     }
  258.  
  259.     RegCloseKey(hKey);
  260.     delete[] szKeyBuf;
  261.     return TRUE;
  262. }
  263.  
  264.  
  265. //
  266. // Create a key and set its value.
  267. BOOL setNamedValue(LPCTSTR szKey,
  268.                    LPCTSTR szSubkey,
  269.                    LPCTSTR szKeyName,
  270.                    LPCTSTR szValue)
  271. {
  272.     HKEY hKey;
  273.     LPTSTR szKeyBuf;
  274.  
  275.     if (szKey == NULL) return FALSE;
  276.  
  277.     // Allocate space
  278.     szKeyBuf = new TCHAR[lstrlen(szKey) + lstrlen(szSubkey) + 2];
  279.     if (!szKeyBuf) return FALSE;
  280.  
  281.     // Copy keyname into buffer.
  282.     _tcscpy(szKeyBuf, szKey);
  283.  
  284.     // Add subkey name to buffer.
  285.     if (szSubkey != NULL)
  286.     {
  287.         _tcscat(szKeyBuf, _T("\\"));
  288.         _tcscat(szKeyBuf, szSubkey );
  289.     }
  290.  
  291.     // Create and open key and subkey.
  292.     long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT,
  293.                                   szKeyBuf,
  294.                                   0, NULL, REG_OPTION_NON_VOLATILE,
  295.                                   KEY_ALL_ACCESS, NULL,
  296.                                   &hKey, NULL);
  297.     if (lResult != ERROR_SUCCESS)
  298.     {
  299.         delete[] szKeyBuf;
  300.         return FALSE ;
  301.     }
  302.  
  303.     // Set the Value.
  304.     if (szValue != NULL)
  305.     {
  306.         RegSetValueEx(hKey, szKeyName, 0, REG_SZ,
  307.                       (BYTE *)szValue,
  308.                       sizeof(TCHAR) * ( _tcslen(szValue)+1) );
  309.     }
  310.  
  311.     RegCloseKey(hKey);
  312.     delete[] szKeyBuf;
  313.     return TRUE;
  314. }
  315.